extends Node3D

@export var unit_scene: PackedScene = preload("res://scenes/Unit.tscn")

var board_manager
var camera_controller  
var shop_ui
var economy_manager

var current_hovered_tile: Vector2i = Vector2i(-1, -1)
var placed_units = {}
var selected_unit_data: UnitData = null
var bench_units: Array = []

func _ready():
	print("=== UnitManager._ready() START ===")
	print("Current node path: ", get_path())
	
	# Wait for the scene tree to be ready
	await get_tree().process_frame
	
	# Try different methods to get the board manager
	board_manager = get_node_or_null("../Board")  # Try relative path first
	if not board_manager:
		board_manager = get_node_or_null("/root/Main/Board")  # Try absolute path
	if not board_manager:
		board_manager = get_tree().get_nodes_in_group("board").front()  # Try group
	
	camera_controller = get_node_or_null("../CameraController")
	if not camera_controller:
		camera_controller = get_node_or_null("/root/Main/CameraController")
	
	shop_ui = get_node_or_null("../UI/ShopPanel")
	if not shop_ui:
		shop_ui = get_node_or_null("/root/Main/UI/ShopPanel")
	
	economy_manager = get_node_or_null("../EconomyManager")
	if not economy_manager:
		economy_manager = get_node_or_null("/root/Main/EconomyManager")
	
	print("Board manager found: ", board_manager != null)
	if board_manager:
		print("Board manager path: ", board_manager.get_path())
		print("Board manager class: ", board_manager.get_class())
		
	print("Camera controller found: ", camera_controller != null)
	print("Shop UI found: ", shop_ui != null)
	print("Economy manager found: ", economy_manager != null)
	
	if shop_ui and shop_ui.has_signal("unit_purchased"):
		shop_ui.unit_purchased.connect(_on_unit_purchased)
		print("Connected to shop UI")
	
	# Connect to board manager signals
	if board_manager:
		print("Checking for signals on board_manager...")
		var signal_list = board_manager.get_signal_list()
		print("Available signals: ", signal_list.size())
		for sig in signal_list:
			print("  - ", sig.name)
		
		if board_manager.has_signal("tile_clicked"):
			var err = board_manager.tile_clicked.connect(_on_tile_clicked)
			print("Connected to tile_clicked signal, result: ", err)
		else:
			print("WARNING: tile_clicked signal not found!")
			
		if board_manager.has_signal("tile_hovered"):  
			var err = board_manager.tile_hovered.connect(_on_tile_hovered)
			print("Connected to tile_hovered signal, result: ", err)
	else:
		print("ERROR: Board manager not found!")
		print("Checking scene tree...")
		print_tree()
	
	print("=== UnitManager._ready() END ===")

func _unhandled_key_input(event):
	# Debug: Press 'T' to test spawn a FREE unit at position 5,2 (DEBUG ONLY)
	if event is InputEventKey and event.pressed and event.keycode == KEY_T:
		print("DEBUG MODE: T key pressed - Spawning FREE test unit at position 5,2")
		print("  board_manager is null: ", board_manager == null)
		if board_manager:
			print("  board_manager path: ", board_manager.get_path())
			var occupied = board_manager.is_tile_occupied(5, 2)
			print("  Tile (5,2) occupied: ", occupied)
			if not occupied:
				# Create a debug unit for testing (FREE - no gold cost)
				var debug_unit_data = UnitData.new()
				debug_unit_data.unit_name = "Debug Unit"
				debug_unit_data.tier = 1
				debug_unit_data.cost = 0  # FREE for testing
				debug_unit_data.max_health = 100
				debug_unit_data.attack_damage = 10
				debug_unit_data.attack_speed = 1.0
				debug_unit_data.movement_speed = 5
				debug_unit_data.attack_range = 2
				debug_unit_data.unit_class = "Debug"
				debug_unit_data.model_color = Color(0.5, 0.5, 0.5)
				
				spawn_unit_from_data(5, 2, debug_unit_data)
				print("DEBUG: Free test unit spawned successfully")
			else:
				print("DEBUG: Tile is occupied")
		else:
			print("DEBUG: board_manager is null - trying to find it again...")
			board_manager = get_node_or_null("../Board")
			if board_manager:
				print("  Found board_manager at ../Board!")

# Only used for legacy BoardManager (not GridMapBoardManager)
func _input(event):
	# Don't process if we're using GridMapBoardManager
	if board_manager and board_manager.has_signal("tile_clicked"):
		return
		
	if event is InputEventMouseMotion:
		handle_mouse_hover()
	
	if event.is_action_pressed("mouse_left"):
		handle_unit_placement()
	
	if event.is_action_pressed("mouse_right"):
		handle_unit_removal()

func handle_mouse_hover():
	if not camera_controller:
		return
		
	var mouse_pos = get_viewport().get_mouse_position()
	
	# Try to get world position from camera_controller
	var world_pos = Vector3.ZERO
	if camera_controller.has_method("get_mouse_world_position"):
		world_pos = camera_controller.get_mouse_world_position(mouse_pos)
	else:
		# Fallback: do our own raycast
		var camera = get_viewport().get_camera_3d()
		if camera:
			var from = camera.project_ray_origin(mouse_pos)
			var to = from + camera.project_ray_normal(mouse_pos) * 1000
			var space_state = camera.get_world_3d().direct_space_state
			var ray_query = PhysicsRayQueryParameters3D.create(from, to)
			ray_query.collision_mask = 1
			var result = space_state.intersect_ray(ray_query)
			if result:
				world_pos = result.position
	
	if world_pos != Vector3.ZERO:
		var tile_pos = board_manager.get_tile_at_position(world_pos)
		
		if current_hovered_tile != tile_pos:
			if current_hovered_tile.x >= 0:
				board_manager.unhighlight_tile(current_hovered_tile.x, current_hovered_tile.y)
			
			current_hovered_tile = tile_pos
			
			if board_manager.is_player_zone(tile_pos.y):
				board_manager.highlight_tile(tile_pos.x, tile_pos.y)

func handle_unit_placement():
	if current_hovered_tile.x < 0:
		return
	
	if not board_manager.is_player_zone(current_hovered_tile.y):
		print("Can only place units in player zone!")
		return
	
	if board_manager.is_tile_occupied(current_hovered_tile.x, current_hovered_tile.y):
		print("Tile already occupied!")
		return
	
	if selected_unit_data:
		spawn_unit_from_data(current_hovered_tile.x, current_hovered_tile.y, selected_unit_data)
		selected_unit_data = null
	else:
		spawn_unit(current_hovered_tile.x, current_hovered_tile.y, true)

func handle_unit_removal():
	if current_hovered_tile.x < 0:
		return
		
	var key = str(current_hovered_tile.x) + "," + str(current_hovered_tile.y)
	if placed_units.has(key):
		var unit = placed_units[key]
		unit.queue_free()
		placed_units.erase(key)
		board_manager.set_tile_occupied(current_hovered_tile.x, current_hovered_tile.y, false)
		print("Unit removed from tile: ", current_hovered_tile)

func spawn_unit(grid_x: int, grid_z: int, is_player: bool) -> Node3D:
	print("=== spawn_unit called: ", grid_x, ", ", grid_z, ", is_player: ", is_player)
	
	if not unit_scene:
		print("ERROR: unit_scene is null!")
		return null
		
	var unit = unit_scene.instantiate()
	if not unit:
		print("ERROR: Failed to instantiate unit!")
		return null
		
	var world_pos = board_manager.get_tile_world_position(grid_x, grid_z)
	print("World position for unit: ", world_pos)
	
	unit.position = world_pos
	unit.position.y = 0
	unit.initialize(grid_x, grid_z, is_player)
	
	if is_player:
		var mat = unit.get_node("MeshInstance3D").get_surface_override_material(0)
		if mat:
			mat.albedo_color = Color(0.2, 0.6, 0.9, 1)
	else:
		var mat = unit.get_node("MeshInstance3D").get_surface_override_material(0)
		if mat:
			mat.albedo_color = Color(0.9, 0.3, 0.3, 1)
	
	# Since UnitManager IS the Units node, add child directly
	add_child(unit)
	print("Unit added as child to Units container")
	
	board_manager.set_tile_occupied(grid_x, grid_z, true)
	
	var key = str(grid_x) + "," + str(grid_z)
	placed_units[key] = unit
	
	print("Unit placed at tile: ", Vector2i(grid_x, grid_z))
	return unit

func spawn_test_units():
	spawn_unit(1, 1, true)
	spawn_unit(3, 1, true)
	spawn_unit(5, 1, true)
	
	spawn_unit(1, 6, false)
	spawn_unit(3, 6, false)
	spawn_unit(5, 6, false)

func spawn_unit_from_data(grid_x: int, grid_z: int, unit_data: UnitData) -> Node3D:
	print("=== spawn_unit_from_data called: ", grid_x, ", ", grid_z)
	
	if not unit_scene:
		print("ERROR: unit_scene is null!")
		return null
		
	var unit = unit_scene.instantiate()
	if not unit:
		print("ERROR: Failed to instantiate unit!")
		return null
		
	var world_pos = board_manager.get_tile_world_position(grid_x, grid_z)
	
	unit.position = world_pos
	unit.position.y = 0
	unit.initialize(grid_x, grid_z, true)
	
	unit.unit_name = unit_data.unit_name
	unit.max_health = unit_data.max_health
	unit.current_health = unit_data.max_health
	unit.attack_damage = unit_data.attack_damage
	unit.attack_speed = unit_data.attack_speed
	unit.movement_speed = unit_data.movement_speed
	unit.attack_range = unit_data.attack_range
	unit.tier = unit_data.tier
	unit.cost = unit_data.cost
	
	var mesh_instance = unit.get_node("MeshInstance3D")
	if mesh_instance:
		var mat = StandardMaterial3D.new()
		mat.albedo_color = unit_data.model_color
		mat.roughness = 0.5
		mat.metallic = 0.2
		mesh_instance.set_surface_override_material(0, mat)
	
	# Since UnitManager IS the Units node, add child directly
	add_child(unit)
	board_manager.set_tile_occupied(grid_x, grid_z, true)
	
	var key = str(grid_x) + "," + str(grid_z)
	placed_units[key] = unit
	
	print("Unit '", unit_data.unit_name, "' placed at tile: ", Vector2i(grid_x, grid_z))
	return unit

func _on_unit_purchased(unit_data: UnitData):
	selected_unit_data = unit_data
	print("Unit purchased from shop: ", unit_data.unit_name, " - Click on board to place")

func _on_tile_clicked(x: int, z: int):
	print("=== UnitManager._on_tile_clicked: ", x, ", ", z, " ===")
	
	if not board_manager:
		print("ERROR: board_manager is null!")
		return
	
	# Handle unit removal with right click FIRST
	if Input.is_action_pressed("mouse_right"):
		var key = str(x) + "," + str(z)
		if placed_units.has(key):
			var unit = placed_units[key]
			
			# Refund half the unit's cost when selling
			if unit.has_method("get_cost") and economy_manager:
				var refund = int(unit.get_cost() / 2)
				economy_manager.add_gold(refund)
				print("Sold unit for ", refund, " gold")
			
			unit.queue_free()
			placed_units.erase(key)
			board_manager.set_tile_occupied(x, z, false)
			print("Unit removed from tile: ", Vector2i(x, z))
		return  # Don't place units when right-clicking
	
	# Check if in player zone (bottom 4 rows: z < 4)
	if z < 4:
		if not board_manager.is_tile_occupied(x, z):
			# Only place units if one was purchased from shop
			if selected_unit_data:
				print("Placing purchased unit: ", selected_unit_data.unit_name)
				spawn_unit_from_data(x, z, selected_unit_data)
				selected_unit_data = null  # Clear selection after placing
			else:
				print("No unit selected! Purchase a unit from the shop first.")
		else:
			print("Tile is occupied")
	else:
		print("Not in player zone (need z < 4, got z = ", z, ")")

func _on_tile_hovered(x: int, z: int):
	current_hovered_tile = Vector2i(x, z)
